package com.sample.thread.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @Author: zg
 * @Date: 2021/11/13
 **/
@Slf4j
public class JsonUtils {

    private static final ObjectMapper OM = new ObjectMapper()
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .registerModules(new ParameterNamesModule(), new Jdk8Module(), new JavaTimeModule())
            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
            .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    /**
     * 对象转换成json（属性必须有get方法）
     * @param obj
     * @return
     */
    public static String toJsonString(Object obj) {
        try {
            String string = OM.writeValueAsString(obj);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            log.warn("", e);
        }
        return null;
    }

    /**
     * json结果集转化为对象
     * @param jsonStr
     * @param beanType
     * @param <T>
     * @return
     */
    public static <T> T jsonToObject(String jsonStr, Class<T> beanType) {
        try {
            T t = OM.readValue(jsonStr, beanType);
            return t;
        } catch (Exception e) {
            //log.warn("", e);
            log.error("序列化失败：{} To {} cause:{}",jsonStr,beanType.getName(),e.getMessage());
        }
        return null;
    }

    /**
     * json转换为对象list
     * @param jsonStr
     * @param beanType
     * @param <T>
     * @return
     */
    public static <T> List<T> jsonToList(String jsonStr, Class<T> beanType) {
        JavaType javaType = OM.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = OM.readValue(jsonStr, javaType);
            return list;
        } catch (Exception e) {
            //log.warn("", e);
            log.error("序列化失败：{} To {} cause:{}",jsonStr,beanType.getName(),e.getMessage());
        }
        return null;
    }

    public static <T> List<T> jsonToList(String jsonStr, Class<T> beanType, Consumer<T> consumer) {
        JavaType javaType = OM.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = OM.readValue(jsonStr, javaType);
            list.forEach(consumer);
            return list;
        } catch (Exception e) {
            //log.warn("", e);
            log.error("序列化失败：{} To {} cause:{}",jsonStr,beanType.getName(),e.getMessage());
        }
        return null;
    }
    public static <T> List<T> jsonToListWithListTypeStr(List<String> jsonStr, Class<T> beanType) {
        List<T> result = null;
        JavaType javaType = OM.getTypeFactory().constructParametricType(List.class, beanType);;
        try {
            if (!CollectionUtils.isEmpty(jsonStr)) {
                result = new ArrayList<>();
                for (String json : jsonStr) {
                    result.addAll(OM.readValue(json, javaType));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            //log.warn("", e);
            log.error("序列化失败：{} To {} cause:{}",jsonStr,beanType.getName(),e.getMessage());
        }
        return result;
    }
    public static <T> List<T> jsonToListWithObjTypeStr(List<String> jsonStr, Class<T> beanType) {
        List<T> result = null;
        //JavaType javaType = OM.getTypeFactory().constructParametricType(List.class, beanType);;
        try {
            if (!CollectionUtils.isEmpty(jsonStr)) {
                result = new ArrayList<>();
                for (String json : jsonStr) {
                    result.add(OM.readValue(json, beanType));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            //log.warn("", e);
            log.error("序列化失败：{} To {} cause:{}",jsonStr,beanType.getName(),e.getMessage());
        }
        return result;
    }

    public static List<Map<String, Object>> jsonToMapList(String jsonStr, Class<Map> mapClass) {
        JavaType javaType = OM.getTypeFactory().constructParametricType(List.class, mapClass);
        try {
            List<Map<String, Object>> list = OM.readValue(jsonStr, javaType);
            return list;
        } catch (Exception e) {
            log.warn("", e);
        }
        return null;
    }



    public static ObjectMapper getOm() {
        return OM;
    }
}
